package cn.yangliu.nacos.comm.oauth;

import java.time.LocalDateTime;

import cn.yangliu.nacos.comm.model.Oauth2Token;
import cn.yangliu.nacos.comm.tools.SpringContextUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * The type of nacos.
 *
 * @author 问道于盲
 * @date 2019 -12-31
 */
public class TokenStore {

    /**
     * current class's static member
     * The constant INSTANCE.
     */
    private static final TokenStore INSTANCE = new TokenStore();
    /**
     * current class instance's member.
     * The Token.
     */
    private String token = "";
    /**
     * current class instance's member.
     * The Expire time.
     */
    private LocalDateTime expireTime = LocalDateTime.now();

    /**
     * Instantiates a new Token store.
     * forbid other class to create a new instance.
     * only itself can create a new instance.
     */
    private TokenStore() {
    }

    /**
     * current class method for getter.
     * Gets instance.
     *
     * @return instance instance
     */
    public static TokenStore getInstance() {
        return INSTANCE;
    }

    /**
     * current class method for setter.
     * Sets token.
     *
     * @param token      the token
     * @param expireTime the expire time
     */
    public synchronized void setToken(String token, LocalDateTime expireTime) {
        /**
         * client 模式的token 设置有效期5分钟
         */
        this.expireTime = expireTime;
        this.token = token;
    }

    /**
     * current class method for getter.
     * Gets token.
     *
     * @return token token
     */
    public String getToken() {
        if (LocalDateTime.now().isBefore(expireTime) && StringUtils.isNotBlank(token)) {
            return token;
        }
        synchronized (this){
            if (LocalDateTime.now().isBefore(expireTime) && StringUtils.isNotBlank(token)) {
                return token;
            }
            Oauth2Service oauth2Service = SpringContextUtils.getBean(Oauth2Service.class);
            Oauth2Token oauth2Token = oauth2Service.loginByClient();
            String accessToken = oauth2Token.getAccessToken();
            Long expiresIn = oauth2Token.getExpiresIn();
            LocalDateTime expiredTime = LocalDateTime.now().plusSeconds(expiresIn);

            setToken(oauth2Token.getTokenType()+ " " + accessToken, expiredTime);
        }

        return this.token;
    }

    /**
     * Reset token.
     */
    public synchronized void resetToken() {
        this.token = null;
    }


}
